#include <config.h>
-#define GTK_INSIDE_BITMASK_C
#include "gtk/gtkbitmaskprivate.h"
#define VALUE_TYPE gsize
#define VALUE_SIZE_BITS (sizeof (VALUE_TYPE) * 8)
#define VALUE_BIT(idx) (((VALUE_TYPE) 1) << (idx))
+struct _GtkBitmask {
+ gsize len;
+ VALUE_TYPE data[1];
+};
+
+static GtkBitmask *
+gtk_bitmask_resize (GtkBitmask *mask,
+ gsize size) G_GNUC_WARN_UNUSED_RESULT;
+static GtkBitmask *
+gtk_bitmask_resize (GtkBitmask *mask,
+ gsize size)
+{
+ gsize i;
+
+ mask = g_realloc (mask, sizeof (GtkBitmask) + sizeof(VALUE_TYPE) * (MAX (size, 1) - 1));
+
+ for (i = mask->len; i < size; i++)
+ mask->data[i] = 0;
+
+ mask->len = size;
+
+ return mask;
+}
+
GtkBitmask *
_gtk_bitmask_new (void)
{
- return g_array_new (FALSE, TRUE, sizeof (VALUE_TYPE));
+ return g_malloc0 (sizeof (GtkBitmask));
}
GtkBitmask *
{
g_return_if_fail (mask != NULL);
- g_array_free (mask, TRUE);
+ g_free (mask);
}
void
* array might have become too large.
* _gtk_bitmask_is_empty() depends on this.
*/
-static void
+static GtkBitmask *
+gtk_bitmask_shrink (GtkBitmask *mask) G_GNUC_WARN_UNUSED_RESULT;
+static GtkBitmask *
gtk_bitmask_shrink (GtkBitmask *mask)
{
guint i;
for (i = mask->len; i; i--)
{
- if (g_array_index (mask, VALUE_TYPE, i - 1))
+ if (mask->data[i - 1])
break;
}
- g_array_set_size (mask, i);
+ return gtk_bitmask_resize (mask, i);
}
GtkBitmask *
g_return_val_if_fail (mask != NULL, NULL);
g_return_val_if_fail (other != NULL, NULL);
- g_array_set_size (mask, MIN (mask->len, other->len));
+ mask = gtk_bitmask_resize (mask, MIN (mask->len, other->len));
for (i = 0; i < mask->len; i++)
{
- g_array_index (mask, VALUE_TYPE, i) &= g_array_index (other, VALUE_TYPE, i);
+ mask->data[i] &= other->data[i];
}
- gtk_bitmask_shrink (mask);
-
- return mask;
+ return gtk_bitmask_shrink (mask);
}
GtkBitmask *
g_return_val_if_fail (mask != NULL, NULL);
g_return_val_if_fail (other != NULL, NULL);
- g_array_set_size (mask, MAX (mask->len, other->len));
+ mask = gtk_bitmask_resize (mask, MAX (mask->len, other->len));
for (i = 0; i < other->len; i++)
{
- g_array_index (mask, VALUE_TYPE, i) |= g_array_index (other, VALUE_TYPE, i);
+ mask->data[i] |= other->data[i];
}
return mask;
for (i = 0; i < other->len; i++)
{
- g_array_index (mask, VALUE_TYPE, i) &= ~g_array_index (other, VALUE_TYPE, i);
+ mask->data[i] |= ~other->data[i];
}
- gtk_bitmask_shrink (mask);
-
- return mask;
+ return gtk_bitmask_shrink (mask);
}
static void
if (array_index >= mask->len)
return FALSE;
- return (g_array_index (mask, VALUE_TYPE, array_index) & VALUE_BIT (bit_index)) ? TRUE : FALSE;
+ return (mask->data[array_index] & VALUE_BIT (bit_index)) ? TRUE : FALSE;
}
GtkBitmask *
if (value)
{
if (array_index >= mask->len)
- g_array_set_size (mask, array_index + 1);
+ mask = gtk_bitmask_resize (mask, array_index + 1);
- g_array_index (mask, VALUE_TYPE, array_index) |= VALUE_BIT (bit_index);
+ mask->data[array_index] |= VALUE_BIT (bit_index);
}
else
{
if (array_index < mask->len)
{
- g_array_index (mask, VALUE_TYPE, array_index) &= ~ VALUE_BIT (bit_index);
- gtk_bitmask_shrink (mask);
+ mask->data[array_index] &= ~ VALUE_BIT (bit_index);
+ mask = gtk_bitmask_shrink (mask);
}
}
for (i = 0; i < mask->len; i++)
{
- if (g_array_index (mask, VALUE_TYPE, i) != g_array_index (other, VALUE_TYPE, i))
+ if (mask->data[i] != other->data[i])
return FALSE;
}
for (i = MIN (mask->len, other->len) - 1; i >= 0; i--)
{
- if (g_array_index (mask, VALUE_TYPE, i) & g_array_index (other, VALUE_TYPE, i))
+ if (mask->data[i] & other->data[i])
return TRUE;
}